/**
 * 全局初始化
 **/
function init() {
    // 时间选择框
    initLayuiDate()
    // 小图标提示
    lay_tipsHover()
    // 渲染选择框
    layui.form ? layui.form.render('select') : ''
};

/**
 * layui 行内 js 执行完成事件相关
 * */
var layLoadEventObj = {
    cardToggle: cardToggle //卡片的关闭显示事件，对应 card id
}
/* 加载完成后执行 */
function layLoadEvent() {
    var keys = Object.keys(layLoadEventObj)
    keys.forEach(function (item) {
        layLoadEventObj[item]()
    })
}

/**
 * iframe 内使用 laydate 高度过小时可使用, 需给 laydate.render 加 trigger: 'click'
 * */
function laydateHeight() {
    if (!frameElement) return;
    frameElement.style['transition'] = 'min-height 0s ease;'
    var $ipdate = (layui.$ || $)('.laydatetime, .laydate, [laydatetime], [laydate]')
    $ipdate.length !== 0 && $ipdate.on('click', function () {
        window.frameElement.style['min-height'] = (this.getBoundingClientRect().bottom + 330) + 'px'
        setTimeout(function () {
            var $laydate = $('.layui-laydate')
            if ($laydate.length == 0) {
                return;
            }
            $laydate[0].addEventListener("DOMNodeRemovedFromDocument", function () {
                window.frameElement.style['min-height'] = '0px'
            })
        }, 300)
    })
}

/**
 * select2 iframe内点击调节高度
 * */
function select2Height(isIframeSon) {
    if (!frameElement) return;
    var $eleSelect = $('select[name][lay-ignore]')
    $eleSelect.on("select2:open", function () {
        var $select2Dro = $('.select2-dropdown').last(),
            _px = 'px'
        curHeight = Math.ceil($select2Dro.offset().top) + $select2Dro.outerHeight(true),
            badHeight = curHeight - (frameElement.style['height'] || 0);
        frameElement.style['min-height'] = curHeight + _px
        $select2Dro.off('resize').on('resize', function () {
            frameElement.style['min-height'] = $(this).offset().top + $(this).outerHeight(true) + _px
        })
    })
}

/**
 * 定获iframeArr_src没有值时，取iframe src 嵌套数组
 *   @param {boolean} isEncodeURI 是否 url编码
 * 
 * 定获iframeArr_src有值时，根据数组iframe src 索引获取iframe
 *  @param {Array} iframeArr_id 索引iframe的id（iframe的src）
 * 
 * 注意：当isEncodeURI设置为false时，用于获取iframe就也要设置isEncodeURI为false
 */
function findIframe(iframeArr_src, isEncodeURI = true) {
    if (!iframeArr_src) {
        var iframeSrcArr = []
        pushPIframeSrc(window.frameElement)
        return isEncodeURI ? encodeURIComponent(JSON.stringify(iframeSrcArr)) : iframeSrcArr

        function pushPIframeSrc(iframe) {
            if (!iframe) return;
            iframeSrcArr.unshift(iframe.getAttribute('src'))
            pushPIframeSrc(iframe.contentWindow.parent.frameElement)
        }
    } else {
        iframeArr_src = JSON.parse(isEncodeURI ? decodeURIComponent(iframeArr_src) : iframeArr_src)
        if (!Array.isArray(iframeArr_src)) return;
        var iframe
        iframeArr_src.forEach(function (item, i) {

            if (!item) return
            var iframeW
            if (!iframe) iframeW = top;
            else iframeW = iframe.contentWindow;
            iframe = iframeW.document.querySelector('iframe[src="' + item + '"]')
        })
        return iframe ? iframe.contentWindow : iframe
    }
}

/**
 * 页面日期输入框自动初始化
 * */
function layuiDateload() {
    var laydate = layui.laydate
    if (!laydate) {
        (layui.$('[laydatetime]').length !== 0 || layui.$('[laydate]').length !== 0) && layui.layer.msg('缺少 laydate 模块')
        return;
    }
    layui.$('[laydatetime]').length !== 0 && layui.$('[laydatetime]').each(function () {
        laydate.render({
            elem: this,
            type: 'datetime',
            trigger: 'click',
            ready: layuiDateDblclick
        });
    });
    layui.$('[laydate]').length !== 0 && layui.$('[laydate]').each(function () {
        laydate.render({
            elem: this,
            type: 'date',
            trigger: 'click',
            ready: layuiDateDblclick
        });
    });

    function layuiDateDblclick() {
        setTimeout(() => { // 双击选中时间
            var tt = layui.$('.layui-laydate .layui-laydate-content tbody')
            tt && tt.length !== 0 && tt.on('dblclick', function () {
                let confirm = layui.$('.layui-laydate-footer [lay-type="confirm"]');
                confirm && confirm.length !== 0 && confirm.click()
            })
        }, 500);
    }
}
// layui时间选择框初始化
function initLayuiDate() {
    layuiDateload();
    laydateHeight();
}

/**
 * 鼠标移到图标上时显示提示信息
 * lay-tips 的 hover 事件
 * */
function lay_tipsHover(id) {
    var $ = layui.$;
    var layer = layui.layer;
    !!id || (id = 'body')
    var $tips = $(id + ' *[lay-tips]')
    if ($tips.length == 0) {
        return;
    }
    $tips.hover(function () {
        var $this = $(this)
        var text = $this.attr('lay-tips'),
            offset = $this.attr('tips-offset') - 12
        this.tips_index = layer.tips(text, this, {
            tips: 3,
            time: 0,
            success: function ($dom, index) {
                if (offset) {
                    $dom.css('margin-left', offset + 'px');
                } else {
                    $dom.css('margin-left', '-12px');
                }
            }
        })
    }, function () {
        layer.close(this.tips_index)
    })
}

/**
 * 防抖
 * */
function debounce(fn, args, wait) {
    if (!fn) {
        return
    }
    //args = (!args) ? {} : args
    wait = (!wait) ? 500 : wait
    var timeout = null; // 创建一个标记用来存放定时器的返回值
    return function () {
        var $this = this
        var $arguments = arguments
        clearTimeout(timeout); // 保证用户输入完之后只有一个setTimeout
        timeout = setTimeout(function () {
            fn.call($this, args, $arguments);
        }, wait);
    };
}

/**
 * 节流
 * */
function reduce(fn, wait) {
    if (!fn) {
        return
    }
    wait = (!wait) ? 500 : wait
    var on = true
    return function () {
        if (!on) return false
        on = false
        fn.apply(this, arguments)
        setTimeout(function () {
            on = true
        }, wait)
    }
}

/**
 * 键盘Enter拥有Tab功能
 * */
function enterTab() {
    var $ = layui.$;
    var $form = $('form:not(.layui-hide)')
    if ($form.length == 0 || !!layui.enterTab) {
        return
    }
    var i = -1,
        isFirst = true

    layui.enterTab = {}
    layui.enterTab.jqSelector = 'div:not(.layui-hide, .my-hide) > div.layui-form-item .layui-input-inline [name]:not(select.select2-hidden-accessible, .layui-disabled, [disabled], .layui-hide), div:not(.layui-hide, .my-hide) > div.layui-form-item .layui-input-inline span.select2:not(.select2-container--disabled) span.select2-selection, > .layui-form-item:last .layui-btn:first',
        layui.enterTab.$inputs = $form.find(layui.enterTab.jqSelector); // 获取表单中的所有输入框 
    $(document).ajaxComplete(reduce(function () {
        if (isFirst) {
            setTimeout(function () {
                layui.enterTab.$inputs = $form.find(layui.enterTab.jqSelector); // 更新表单中的所有输入框  
                isFirst = false
            }, 500)
        }
    }))
    $(document).keydown(function (e) {
        var $inputs = layui.enterTab.$inputs
        if (e.key == 'Enter' || e.which == 13 || e.keycode == 13) { // 判断所按是否回车键
            var $focusI = $form.find('*:focus')
            if ($focusI.length == 0) {
                return;
            }
            if ($focusI[0].tagName != "TEXTAREA" || (($focusI[0].selectionEnd - $focusI[0].selectionStart) == $focusI.val().length || !$focusI.val())) {
                var ti = $inputs.index($focusI);
                (ti == $inputs.length - 1 && i == -1) || (i = (ti == -1) ? i : ti)
                if (i == $inputs.length - 1) { // 判断是否是最后一个输入框
                    i = -1
                    //$form.find('button[lay-submit]').click(); // 提交表单
                }
                if ($focusI.hasClass('layui-btn')) {
                    $focusI.click(); // 当前为按钮，设置点击
                }
                i++
                var nextInput = $inputs[i]
                nextInput.focus(); // 设置焦点
                (nextInput.tagName == "SELECT" || nextInput.tagName == "SPAN") || $(nextInput).hasClass('layui-btn') || nextInput.select(); // 选中文字
                var select_div = $(nextInput).closest(".layui-form-select");
                !select_div || $(select_div).addClass('layui-form-selected');
                return false; // 取消默认的提交行为  
            }
        }
    })
}
/**
 * 异常处理,简化了try...catch...finally 块的书写
 * 若是errFn和endFn返回都有返回值，则值返回endFn函数的返回值。
 * @fn function 要进行的业务逻辑
 * @errFn function 出现异常时进行的处理方法，接收一个参数，为对应的异常。
 */
function err(fn, errFn, endFn) {
    try {
        return fn ? fn() : '';
    } catch (error) {
        console.warn("======发生异常====== 异常为：" + error)
        if (errFn) return typeof errFn === "function" ? errFn(error) : error;
    } finally {
        if (endFn) return typeof endFn === "function" ? endFn() : '';
    }
}

/**
 * 将指定日期时间或当前日期时间转换成指定的格式。
 * format('星期W')                  // 星期日
 * format("YYYY-MM-DD hh:mm:ss")   // 2021-03-21 20:24:32
 * format("MM/DD/YYYY hh:mm")      // 03-21-2021 20:24
 * format("MM/DD/YYYY hh:mm")      // 03-21-2021 20:24 
 * format("YYYY年MM月DD日 hh:mm:ss 星期W") // 2021年03月21日 20:30:14 星期日
 * const a = format("YYYY-MM-DD hh:mm:ss")	// a: 2021-03-21 20:48:30
 * const b = format("YYYY年MM月DD日 hh:mm:ss 周W", 1616330071538)	// b: 2021年03月21日 20:34:31 周日
 * @fmt {String} 日期格式
 * @timestamp {Date} 标准时间。选填。
 */
function format(fmt, timestamp) {
    const date = timestamp ? new Date(timestamp) : new Date()
    const o = {
        "Y+": date.getFullYear(),
        "M+": date.getMonth() + 1, // 月
        "D+": date.getDate(), // 日
        "h+": date.getHours(), // 时
        "m+": date.getMinutes(), // 分
        "s+": date.getSeconds(), // 秒
        "W": date.getDay() // 周
    }
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
            fmt = fmt.replace(RegExp.$1, () => {
                if (k === 'W') { // 星期几
                    const week = ['日', '一', '二', '三', '四', '五', '六']
                    return week[o[k]]
                } else if (k === 'Y+' || RegExp.$1.length == 1) { // 年份 or 小于10不加0
                    return o[k]
                } else {
                    return ("00" + o[k]).substr(("" + o[k]).length) // 小于10补位0
                }
            })
        }
    }
    return fmt
}


/**
 * 卡片的关闭显示事件，对应 card id
 * */
var cardToggle = {
    init: function () {
        var $ = layui.$,
            _this = cardToggle
        /* $('body')    无效?
        	.on('click', '[card-toggle]', _this.toggle)
        	.on('click', '[card-close]', function () {
        		_this.toggle.call(this, false) //执行 toggle，强制为隐藏
        		return false
        	}) */
        $('[card-toggle]').click(_this.toggle)
        $('[card-close]').click(function () {
            _this.toggle.call(this, false) //执行 toggle，强制为隐藏
            return false
        })

        var $active = $('[card-toggle-active]')

        var lastToggleName = localStorage.getItem(location.pathname + ':card-toggle') //当前页面最后一次显示的 card 名称
        if (lastToggleName) {
            //显示 当前页面最后一次显示的 card
            $active = $('[card-toggle="' + lastToggleName + '"]')
        }

        $active.each(function () {
            _this.toggle.call(this, true, false) //执行 toggle，强制为显示, 默认行为强制不缓存
        })
    },
    /**
     * 显隐操作
     * @param {boolean} conShow 强制显隐
     * @param {boolean} conCache 强制是非缓存
     * */
    toggle: function (conShow, conCache) {
        var $this = $(this),
            isCardClose = $this[0].hasAttribute('card-close'), //是否为关闭按钮
            cardName = isCardClose ? $this.attr('card-close') : $this.attr('card-toggle'), //要切换的 card 名称
            cardType = $this.attr('card-type'), //card 类型，存在该值则永每次切换只显示其中一个
            $card = $('#' + cardName).add($('[card-content="' + cardName + '"]')), //id 为 cardName、[card-content=cardName] 均为 card 体
            curIsHide = $.type(conShow) === 'boolean' ? conShow : $card.is(':hidden'), //判断是否有传入参数来强制显隐，否则取 当前 card 显示状态
            isCache = $.type(conCache) === 'boolean' ? conCache : this.hasAttribute('card-toggle-cache') //是否缓存操作
        if (cardType) {
            $this.removeClass('toggle-active')
            $('[card-toggle][card-type="' + cardType + '"]:not([card-toggle="' + cardName + '"])').removeClass('toggle-active') //取消聚焦样式其他相同 card 类型按钮
            $('[card-content][card-type="' + cardType + '"]:not([card-content="' + cardName + '"])').hide() //隐藏其他此 card 类型 体
        }

        if (curIsHide) {
            $('[card-toggle="' + cardName + '"]').addClass('toggle-active') //按钮聚焦
            $card.show() //card体显示
        } else {
            $('[card-toggle="' + cardName + '"]').removeClass('toggle-active') //按钮取消聚焦
            $card.hide() //card体隐藏
        }

        if (isCache) {
            //缓存操作
            localStorage.setItem(location.pathname + ':card-toggle', curIsHide ? cardName : '') //缓存暂时只保存一个
        }
    }
}


var cardToggle = {
    init: function () {
        var $ = layui.$,
            _this = cardToggle
        /* $('body')    无效?
        	.on('click', '[card-toggle]', _this.toggle)
        	.on('click', '[card-close]', function () {
        		_this.toggle.call(this, false) //执行 toggle，强制为隐藏
        		return false
        	}) */
        $('[card-toggle]').click(_this.toggle)
        $('[card-close]').click(function () {
            _this.toggle.call(this, false) //执行 toggle，强制为隐藏
            return false
        })

        var $active = $('[card-toggle-active]')

        var lastToggleName = localStorage.getItem(location.pathname + ':card-toggle') //当前页面最后一次显示的 card 名称
        if (lastToggleName) {
            //显示 当前页面最后一次显示的 card
            $active = $('[card-toggle="' + lastToggleName + '"]')
        }

        $active.each(function () {
            _this.toggle.call(this, true, false) //执行 toggle，强制为显示, 默认行为强制不缓存
        })
    },
    /**
     * 显隐操作
     * @param {boolean} conShow 强制显隐
     * @param {boolean} conCache 强制是非缓存
     * */
    toggle: function (conShow, conCache) {
        var $this = $(this),
            isCardClose = $this[0].hasAttribute('card-close'), //是否为关闭按钮
            cardName = isCardClose ? $this.attr('card-close') : $this.attr('card-toggle'), //要切换的 card 名称
            cardType = $this.attr('card-type'), //card 类型，存在该值则永每次切换只显示其中一个
            $card = $('#' + cardName).add($('[card-content="' + cardName + '"]')), //id 为 cardName、[card-content=cardName] 均为 card 体
            curIsHide = $.type(conShow) === 'boolean' ? conShow : $card.is(':hidden'), //判断是否有传入参数来强制显隐，否则取 当前 card 显示状态
            isCache = $.type(conCache) === 'boolean' ? conCache : this.hasAttribute('card-toggle-cache') //是否缓存操作
        if (cardType) {
            $this.removeClass('toggle-active')
            $('[card-toggle][card-type="' + cardType + '"]:not([card-toggle="' + cardName + '"])').removeClass('toggle-active') //取消聚焦样式其他相同 card 类型按钮
            $('[card-content][card-type="' + cardType + '"]:not([card-content="' + cardName + '"])').hide() //隐藏其他此 card 类型 体
        }

        if (curIsHide) {
            $('[card-toggle="' + cardName + '"]').addClass('toggle-active') //按钮聚焦
            $card.show() //card体显示
        } else {
            $('[card-toggle="' + cardName + '"]').removeClass('toggle-active') //按钮取消聚焦
            $card.hide() //card体隐藏
        }

        if (isCache) {
            //缓存操作
            localStorage.setItem(location.pathname + ':card-toggle', curIsHide ? cardName : '') //缓存暂时只保存一个
        }
    }
}
layLoadEventObj['cardToggle'] = cardToggle['init'] //layui 行内 js 执行完成后执行